package com.sunshine.wheel.study.netty.chat.server.handler;

import com.sunshine.wheel.study.netty.chat.util.FileUtils;
import io.netty.channel.*;
import io.netty.handler.codec.http.*;

import java.io.RandomAccessFile;

/**
 * 进行THHP处理的处理器
 */
public class HttpHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        if (request != null) {
            // 获取请求资源
            RandomAccessFile randomAccessFile = null;
            try {
                String baseUri = HttpHandler.class.getProtectionDomain().getCodeSource().getLocation().toURI() + "/webroot";
                String reqUri = request.uri();
                String fileName = reqUri.equals("/") ? "chat.html" : reqUri;;
                randomAccessFile = new RandomAccessFile(FileUtils.getFile(baseUri, fileName), "r");
            } catch (Exception e) {
                ctx.fireChannelRead(request.retain());
                return;
            }

            // 构造HTTP响应对象
            HttpResponse response = new DefaultHttpResponse(request.protocolVersion(), HttpResponseStatus.OK);
            // 判断是否是Keep-Alive，如果是，则在应答消息头中设置Connection为Keep-Alive
            boolean keepAlive = HttpUtil.isKeepAlive(request);
            if (keepAlive) {
                response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
            }
            // 设置MIME类型
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, getContentType(request));
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, randomAccessFile.length());

            ctx.write(response);
            ctx.write(new DefaultFileRegion(randomAccessFile.getChannel(), 0, randomAccessFile.length()));
            ChannelFuture future = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
            if (!keepAlive) {
                future.addListener(ChannelFutureListener.CLOSE);
            }
            randomAccessFile.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }


    /**
     * 获取MIME类型
     * @param request   HTTP请求
     * @return
     */
    private String getContentType(FullHttpRequest request ) {
        final String reqUri = request.uri();
        String contextType = "text/html;";
        if(reqUri.endsWith(".css")){
            contextType = "text/css;";
        }else if(reqUri.endsWith(".js")){
            contextType = "text/javascript;";
        }else if(reqUri.toLowerCase().matches("(jpg|png|gif)$")){
            String ext = reqUri.substring(reqUri.lastIndexOf("."));
            contextType = "image/" + ext;
        }
        return contextType;
    }

}
